package com.jar.exercise.多线程.synchroniz;

/**
 * <div  style="border:2px solid none;margin:20px;padding:15px;font-size:24px;text-align:center;color:aqua;">
 *
 *  synchronized 方法上相关的操作
 *
 *  1. 不论是同步静态方法还是普通静态方法，当有任意一个线程访问同步方法，那么当前类中所有的永不静态方法或者同步方法都将被锁
 *  2. 同步代码块， 如果是 对象实例，当任意一个线程访问该对象实例，那么该代码块会锁住剩余的线程的访问
 *  3.  同步代码块， 如果是 对象名(Demo.class) 那么如果只会锁住Demo 类的访问其他的类将不会被锁.
 *
 *  </div>
 *
 * @author RichMan
 * @date 2021-03-13 19:17
 */
public class 静态方法上SynchronizedTest {

    public static void main(String[] args) {

        静态方法上SynchronizedTest a = new 静态方法上SynchronizedTest();

        // 第一个线程去访问 对象的 第一个方法
        new Thread(() -> {
            静态方法上SynchronizedTest.t1();
        }).start();

        // 第二个线程去访问 对象的 第二个方法
        new Thread(() -> {
            静态方法上SynchronizedTest.t2();
        }).start();


        // 第三个线程去访问 对象的 第三个方法
        new Thread(() -> {
            a.t3();
        }).start();


        new Thread(() -> {
            a.t4();
        }).start();


        new Thread(() -> {
            a.t5();
        }).start();


        // 一个对象 如果有多个 静态同步方法 ， 只要有线程访问其中一个方法，其他的方法也会被锁定。
        // 执行结果 可以看出，两个线程分别的访问两个方法但是只能有一个可以访问另一个必须等待

    }




    private static synchronized void t1(){
        System.out.println("---- 开始访问 t1 ----");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("---- 结束访问 t1 ----");
    }


    private static synchronized void t2(){
        System.out.println("---- 开始访问 t2 ----");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("---- 结束访问 t2 ----");
    }

    private void t3(){

        System.out.println("---- 进入访问 t3 ----");

        synchronized (SubClass.class){
            System.out.println("---- 开始访问 t3 ----");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("---- 结束访问 t3 ----");
        }
        System.out.println("---- 退出访问 t3 ----");

    }

    private void t4(){

        System.out.println("---- 进入访问 t4 ----");

        synchronized (SubClass.class){
            System.out.println("---- 开始访问 t4 ----");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("---- 结束访问 t4 ----");
        }
        System.out.println("---- 退出访问 t4 ----");

    }

    private synchronized void t5(){
        System.out.println("---- 开始访问 t5 ----");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("---- 结束访问 t5 ----");
    }

    /**
     *  代码块 和 静态方法
     */
    static class SubClass{
        public static void main(String[] args) {

            静态方法上SynchronizedTest a = new 静态方法上SynchronizedTest();

            // 第一个线程去访问 对象的 第一个方法
            new Thread(() -> {
                静态方法上SynchronizedTest.t1();
            }).start();

            // 第二个线程去访问 对象的 第二个方法
            new Thread(() -> {
                静态方法上SynchronizedTest.t2();
            }).start();


            // 第三个线程去访问 对象的 第三个方法
            new Thread(() -> {
                a.t3();
            }).start();

            // 第四个线程去访问 对象的 第四个方法
            new Thread(() -> {
                a.t4();
            }).start();


            // 一个对象 如果有多个 静态同步方法 ， 只要有线程访问其中一个方法，其他的方法也会被锁定。
            // 执行结果 可以看出，两个线程分别的访问两个方法但是只能有一个可以访问另一个必须等待

        }
    }


    static class Sub2Class{
        public static void main(String[] args) {

            静态方法上SynchronizedTest a = new 静态方法上SynchronizedTest();

            // 第三个线程去访问 对象的 第三个方法
            new Thread(() -> {
                a.t5();
            }).start();

            // 第四个线程去访问 对象的 第四个方法
            new Thread(() -> {
                静态方法上SynchronizedTest.t1();
            }).start();

        }
    }

    static class Sub3Class{
        public static void main(String[] args) {

            静态方法上SynchronizedTest a = new 静态方法上SynchronizedTest();


            // 第三个线程去访问 对象的 第三个方法
            new Thread(() -> {
                a.t3();
            }).start();

            // 第四个线程去访问 对象的 第四个方法
            new Thread(() -> {
                a.t4();
            }).start();


        }
    }



}
